package com.jqj.example;

import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @Desc:
 * @Author: lijingzheng
 * @Date: 2024/12/13
 */
public class LockTest {

    public static void main3(String[] args) throws IOException {

        Semaphore semaphore = new Semaphore(1);

        CompletableFuture.runAsync(() -> {
            try {
                semaphore.acquire();
                semaphore.tryAcquire();
                semaphore.tryAcquire(10, TimeUnit.SECONDS);
                TimeUnit.SECONDS.sleep(30);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            semaphore.release();
        });

        try {
            TimeUnit.SECONDS.sleep(10);
            semaphore.acquire();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        semaphore.release();

        System.in.read();
    }

    public static void main2(String[] args) throws IOException {

        ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();

        CompletableFuture.runAsync(() -> {
            reentrantReadWriteLock.writeLock().lock();
            try {
                TimeUnit.SECONDS.sleep(30);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            // 写锁降级为读锁读锁
            reentrantReadWriteLock.readLock().lock();

            reentrantReadWriteLock.writeLock().unlock();

            try {
                TimeUnit.SECONDS.sleep(60);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            reentrantReadWriteLock.readLock().unlock();
        });

        try {
            TimeUnit.SECONDS.sleep(10);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        reentrantReadWriteLock.readLock().lock();
        try {
            TimeUnit.SECONDS.sleep(30);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        reentrantReadWriteLock.readLock().unlock();

        System.in.read();
    }

    public static void main1(String[] args) throws IOException {

//        LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(2));
//        boolean interrupted = Thread.interrupted();

        ReentrantLock reentrantLock = new ReentrantLock();

        CompletableFuture.runAsync(() -> {
            reentrantLock.lock();
            try {
                TimeUnit.SECONDS.sleep(30);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            reentrantLock.unlock();
        });

        try {
            TimeUnit.SECONDS.sleep(10);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        reentrantLock.lock();
//        reentrantLock.tryLock();
//        reentrantLock.tryLock(100, TimeUnit.SECONDS);
        try {
            TimeUnit.SECONDS.sleep(30);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        reentrantLock.unlock();

        System.in.read();
    }

    public static void main(String[] args) throws IOException {

        ReentrantLock reentrantLock = new ReentrantLock();
        Condition conditionA = reentrantLock.newCondition();
        Condition conditionB = reentrantLock.newCondition();

        CompletableFuture.runAsync(() -> {
            reentrantLock.lock();
            try {
                TimeUnit.SECONDS.sleep(10);
                conditionA.await();
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            reentrantLock.unlock();
        });

        CompletableFuture.runAsync(() -> {
            reentrantLock.lock();
            try {
                TimeUnit.SECONDS.sleep(10);
//                conditionA.await();
                conditionB.await();
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            reentrantLock.unlock();
        });

        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        reentrantLock.lock();
        try {
            TimeUnit.SECONDS.sleep(10);
            conditionA.signal();
            conditionA.signalAll();
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        reentrantLock.unlock();

        System.in.read();
    }


}
